package com.home.security.browser.shiro;

import com.home.common.utils.object.ObjectUtils;
import com.home.common.utils.spring.SpringUtils;
import com.home.common.model.CurrentUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.Authenticator;
import org.apache.shiro.authc.LogoutAware;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisSessionDAO;

import java.util.Collection;

/**
 * Description:
 * Created by 王大宸 on 2020-11-14 2:09
 * Created with IntelliJ IDEA.
 */
public class ShiroUtils {
    private static final RedisSessionDAO redisSessionDAO = SpringUtils.getBean(RedisSessionDAO.class);

    /**
     * 获取当前用户Session
     */
    public static Session getSession() {
        return SecurityUtils.getSubject().getSession();
    }

    /**
     * 获取当前用户SessionId
     */
    public static String getSessionId() {
        return String.valueOf(getSession().getId());
    }

    /**
     * 用户登出
     */
    public static void logout() {
        SecurityUtils.getSubject().logout();
    }

    /**
     * 获取 ip
     */
    public static String getIp() {
        return getSession().getHost();
    }

    /**
     * 获取当前用户信息
     */
    public static CurrentUser getUserInfo() {
        return ObjectUtils.objToClass(SecurityUtils.getSubject().getPrincipal(), CurrentUser.class);
    }

    public static String getUserId() {
        return getUserInfo().getId();
    }

    /***
     * 功能说明：删除用户缓存信息,并重新加载权限
     *
     * @author 王大宸
     * @date 2020/7/3 17:23
     * @param username          登录账号
     * @param clientId          客户端
     * @param isRemoveSession   是否删除缓存
     * @return void
     */
    public static void deleteCache(String username, String clientId, boolean isRemoveSession) {
        // 删除缓存中的 Session
        Object attribute = removeCache(username, clientId, isRemoveSession);
        //删除Cache，在访问受限接口时会重新授权
        DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
        Authenticator authc = securityManager.getAuthenticator();
        ((LogoutAware) authc).onLogout((SimplePrincipalCollection) attribute);
    }

    /***
     * 功能说明：删除用户缓存
     *
     * @author 王大宸
     * @date 2020/7/3 17:23
     * @param username           用户登录账号
     * @param isRemoveSession    是否删除缓存
     * @param clientId           客户端
     * @return java.lang.Object
     */
    public static Object removeCache(String username, String clientId, boolean isRemoveSession) {
        //从缓存中获取Session
        Session session = null;
        Collection<Session> sessions = redisSessionDAO.getActiveSessions();
        CurrentUser user;
        Object attribute = null;
        for (Session sessionInfo : sessions) {
            // 遍历Session,找到该用户名称对应的Session
            attribute = sessionInfo.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if (attribute == null) {
                continue;
            }
            Object primaryPrincipal = ((SimplePrincipalCollection) attribute).getPrimaryPrincipal();
            user = ObjectUtils.objToClass(primaryPrincipal, CurrentUser.class);
            if (null == user) {
                continue;
            }
            // 挤下同一客户端下的账号,保证每个客户端的登录账号唯一
            if (username.equals(user.getUsername()) && clientId.equals(user.getClientId())) {
                session = sessionInfo;
                break;
            }
        }
        if (null == session) {
            return null;
        }
        //删除session
        if (isRemoveSession) {
            redisSessionDAO.delete(session);
        }
        return attribute;
    }

    /**
     * 删除登录缓存
     *
     * @param sessionId sessionId
     */
    public static void removeSession(String sessionId) {
        Session session = redisSessionDAO.readSession(sessionId);
        redisSessionDAO.delete(session);
    }

}
